#include <iostream>


/*
关于深浅拷贝的理解：

深拷贝：拷贝指针指向的地址，拷贝指针指向的地址所指向的内存，拷贝指针指向的地址所指向的内存中的数据。

浅拷贝：拷贝指针指向的地址，拷贝指针指向的地址所指向的内存，但是不拷贝指针指向的地址所指向的内存中的数据。

  在C/C++中，结构体/对象的拷贝通常使用赋值运算符（=）来完成。
  如果结构体中包含指针，那么默认的拷贝操作是浅拷贝，通过上面的讲解可知如果直接用=来创建结构体/对象的拷贝，如果其一个结构体/对象对指针成员指向的内容进行修改就会影响到其他的结构体/对象的拷贝。
  因此在创建结构体/对象的拷贝需要使用深拷贝，需要手动实现数据的复制。

*/




template <typename T>
class DeepCopy
{
private:
    T *data;//带有指针成员变量
public:
    DeepCopy(T *data)
    {
        if (data) {
            this->data = new T(*data);
        } else {
            this->data = nullptr;
        }
    }

    ~DeepCopy()
    {
        std::cout << "Destructor of DeepCopy called" << std::endl;
        if(this->data)
        {

            std::cout << "Deleting data" << std::endl;
            delete this->data;
            /* code */
        }
        
            
    }

    DeepCopy(const DeepCopy &original)
    {
        this->data = new T(*original.data);//深拷贝，拷贝指针指向的地址
    }

    DeepCopy &operator=(const DeepCopy &original)
    {
        if (this == &original) {
            return *this;
        }
        delete data;
        this->data = new T(*original.data);
        return *this;
    }

    T *getData() const { return data; }
    void setData(T *data) { this->data = data; }
};


class ShallowCopy
{
private:
    int *data;
public:
    ShallowCopy(int *data)
    {
        this->data = data;
    }

    ShallowCopy(const ShallowCopy &original)
    {
        this->data = original.data;
    }

    ShallowCopy &operator=(const ShallowCopy &original)
    {
        if (this == &original) {
            return *this;
        }
        this->data = original.data;
        return *this;
    }

    int *getData() const { return data; }
    void setData(int *data) { this->data = data; }
};



int main(int argc, char const *argv[])
{
    int a = 10;
    DeepCopy<int> origin(&a);
    DeepCopy<int> copy(origin);

    std::cout << "copy.getData():" << *(copy.getData()) << std::endl;
    std::cout << "origin.getData():" << *(origin.getData()) << std::endl;

    int b  = 20;
    // origin.setData(&b);
    a = 30;
    
    std::cout << "copy.getData():" << *(copy.getData()) << std::endl;
    std::cout << "origin.getData():" << *(origin.getData()) << std::endl;

    return 0;
}
